import { BNode } from '../type/BNode';
import { IEvent } from '../type/IEvent';
import { TaskState } from '../type/TaskState';

/**
 * 并行树
 * 同时执行每个节点,直到所有节点执行完毕
 */
export class ParallelTree extends BNode implements IEvent {
    public children: IEvent[] = [];
    private checkArray: number[] = [];
    private iTime: number = 0;

    addChild(...nodes: IEvent[]) {
        for (const n of nodes) {
            this.children.push(n);
        }
    }

    onUpdate(dt: number): void {
        if (this.getState() != TaskState.running) {
            return;
        }
        this.iTime += dt;
        this.checkArray.length = this.children.length;
        for (let i = 0; i < this.children.length; i++) {
            const node = this.children[i];
            if (node.task.getState() === TaskState.pending) {
                node.task.running();
                node.onStart(this.blackBoard);
            }
            if (node.task.getState() === TaskState.running) {
                node.onUpdate(dt);
            }

            this.checkArray[i] = node.task.getState();
            if (this.isDone()) {
                this.task.done();
                return;
            }
        }
    }

    onCancel(): void {
        this.task.error();
        this.checkArray = [];
    }

    getState(): TaskState {
        return this.task.getState();
    }

    private isDone() {
        for (let i = 0; i < this.checkArray.length; i++) {
            if (!(this.checkArray[i] === TaskState.done || this.checkArray[i] === TaskState.error)) {
                return false;
            }
        }
        return true;
    }

    onReset(): void {
        this.children.forEach((value) => {
            value.task.reset();
            value.onReset();
        });
        this.task.done();
    }

    onEvent(event: string, data?: any): void {
        for (let i = 0; i < this.children.length; i++) {
            this.children[i].onEvent(event, data);
        }
    }
}
